package org.gd.spring.mongodb;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import org.gd.mongodb.MongoTestUser;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Query;

import static org.springframework.data.mongodb.core.query.Criteria.where;

public class App {

    public static void main(String[] args) {

        // For XML
        // ApplicationContext ctx = new GenericXmlApplicationContext("mongo-config.xml");

        // For Annotation
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringMongoConfig.class);

        MongoOperations mongoOperation = ctx.getBean("mongoTemplate", MongoOperations.class);

        User user = new User("mkyong", "password123");

        // save
        mongoOperation.save(user, "users");

        // find
        User savedUser = mongoOperation.findOne(
                new Query(
                        where("username").is("mkyong")
                ), User.class, "users"
        );

        /*
        System.out.println("savedUser : " + savedUser);

        // update
        mongoOperation.updateMulti(
                new Query(
                        Criteria.where("username").is("mkyong")
                ),
                Update.update("password", "new password"), "users"
        );

        // find
        User updatedUser = mongoOperation.findOne(
                new Query(
                        Criteria.where("username").is("mkyong")
                ), User.class,"users"
        );

        System.out.println("updatedUser : " + updatedUser);

        // delete
        mongoOperation.remove(
                new Query(
                        Criteria.where("username").is("mkyong")
                ), "users"
        );

        // List
        List<User> listUser = mongoOperation.findAll(User.class, "users");
        System.out.println("Number of user = " + listUser.size());
        */



        long t = System.currentTimeMillis();
        if(mongoOperation.collectionExists("user")) {
            DBCollection collection = mongoOperation.getCollection("user");
            BasicDBObject searchQuery = new BasicDBObject();
            //searchQuery.put("id", 1001);
            //DBCursor cursor = collection.find(searchQuery);
            DBCursor cursor = collection.find();
            if(cursor.size() == 0) {
                System.out.println("lines not found");
            } else {
                while (cursor.hasNext()) {
                    DBObject object = cursor.next();
                    System.out.println(object);

                    //MongoTestUser user = new Gson().fromJson(object.get("user").toString(), MongoTestUser.class);
                    //System.out.println(user);
                }
            }
        }
        t = printTimer("GET", t);

        mongoOperation.remove(new Query(), "yourCollection");
        t = printTimer("remove", t);
        for(int i=0; i<10; i++) {
            long count = mongoOperation.count(new Query(), "yourCollection");
            String name = generateString(new Random(), "name", 10);
            String login = generateString(new Random(), "login", 10);
            mongoOperation.insert(new MongoTestUser(count, name, login), "yourCollection");
        }
        t = printTimer("insert", t);


        System.out.println(mongoOperation.indexOps("yourCollection").getIndexInfo());
        System.out.println(mongoOperation.indexOps("yourCollection").getIndexInfo().get(0));
        System.out.println(mongoOperation.indexOps("yourCollection").getIndexInfo().get(0).getIndexFields().get(0));
        System.out.println(mongoOperation.indexOps("yourCollection").getIndexInfo().get(0).getIndexFields().get(0).getKey());

        System.out.println();


        for (Object o: mongoOperation.find(new Query(
                //Criteria.where("login").is("nlnooonoin")
        ), Object.class, "yourCollection")) {
            System.out.println("Object: " + o);
        }






        List<MongoTestUser> userList = mongoOperation.find(new Query(
                //Criteria.where("login").is("nlnooonoin")
        ), MongoTestUser.class, "yourCollection");
        t = printTimer("get", t);
        for (MongoTestUser user1 : userList) {
            System.out.println("user: " + user1);
        }
        t = printTimer("print", t);

        System.out.println(mongoOperation.count(new Query(), "yourCollection"));
        t = printTimer("count", t);

    }

    public static String generateString(Random rng, String characters, int length) {
        char[] text = new char[length];
        for (int i = 0; i < length; i++) {
            text[i] = characters.charAt(rng.nextInt(characters.length()));
        }
        return new String(text);
    }

    public static long printTimer(String title, long t) {
        System.out.println(title + ": " + new SimpleDateFormat("mm:ss.SSS").format(new Date(System.currentTimeMillis() - t)));
        return System.currentTimeMillis();
    }
}
